﻿using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.ComponentModel;
using System.Reflection;
using System.Security.Cryptography;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Text;

namespace CTP.CRM.Core.PublicMethords
{
    public static class PublicExtensions
    {
        public static string If(this string str, bool condition)
        {
            return condition ? str : string.Empty;
        }

        //
        // 摘要:
        //     获取对象Json序列化结果
        //
        // 参数:
        //   obj:
        public static string ToJson(this object jsonObject)
        {
            return (jsonObject == null) ? null : JsonConvert.SerializeObject(jsonObject);
        }

        //
        // 摘要:
        //     获取字符串的Json反序列化结果
        //
        // 参数:
        //   obj:
        public static T ToObject<T>(this string Json)
        {
            return (T)((Json == null) ? ((object)default(T)) : ((object)JsonConvert.DeserializeObject<T>(Json)));
        }

        //
        // 摘要:
        //     获取对象Json序列化结果，忽略异常
        //
        // 参数:
        //   obj:
        public static string TryToJson(this object obj)
        {
            try
            {
                return obj.ToJson();
            }
            catch
            {
            }

            return "";
        }

        //
        // 摘要:
        //     简单判断一个对象是否是有效json
        //
        // 参数:
        //   jsonStr:
        public static bool IsJson(this string jsonStr)
        {
            return Regex.IsMatch(jsonStr.Trim(), "^(\\{.*\\}|\\[.*\\])$");
        }

        //
        // 摘要:
        //     获取字符串base64
        //
        // 参数:
        //   str:
        public static string GetBase64EncodeString(this string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }

            byte[] bytes = Encoding.UTF8.GetBytes(str);
            return Convert.ToBase64String(bytes);
        }

        //
        // 摘要:
        //     解析base64
        //
        // 参数:
        //   str:
        public static string GetBase64DecodeString(this string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }

            byte[] bytes = Convert.FromBase64String(str);
            return Encoding.UTF8.GetString(bytes);
        }

        //
        // 摘要:
        //     获取字符串MD5
        //
        // 参数:
        //   target:
        //     原串
        //
        //   salt:
        //     盐
        public static string GetMD5(this string target, string salt = "")
        {
            byte[] bytes = Encoding.UTF8.GetBytes(target + (string.IsNullOrEmpty(salt) ? "" : salt));
            return bytes.GetMD5();
        }

        //
        // 摘要:
        //     获得字符MD5
        //
        // 参数:
        //   bytes:
        public static string GetMD5(this byte[] bytes)
        {
            using MD5 mD = MD5.Create();
            byte[] array = mD.ComputeHash(bytes);
            string text = "";
            for (int i = 0; i < array.Length; i++)
            {
                text += ((array[i].ToString("X").Length == 1) ? ("0" + array[i].ToString("X")) : array[i].ToString("X"));
            }

            return text;
        }

        //
        // 摘要:
        //     获取字符串的hash值
        //
        // 参数:
        //   target:
        public static string GetHash(this string target)
        {
            StringBuilder stringBuilder = new StringBuilder();
            byte[] bytes = Encoding.UTF8.GetBytes(target);
            using (SHA1 sHA = SHA1.Create())
            {
                byte[] array = sHA.ComputeHash(bytes);
                byte[] array2 = array;
                foreach (byte b in array2)
                {
                    stringBuilder.Append(b.ToString("x2"));
                }
            }

            return stringBuilder.ToString();
        }

        public static int GetHashRemainder(this string target)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(target);
            using SHA256 sHA = SHA256.Create();
            byte[] array = sHA.ComputeHash(bytes);
            long num = 0L;
            for (int i = 0; i < array.Length; i++)
            {
                num = (num << 8) + array[i];
            }

            int num2 = (int)(num % 10);
            if (num2 < 0)
            {
                num2 = Math.Abs(num2);
            }

            return num2;
        }

        //
        // 摘要:
        //     获取枚举类型的描述
        //
        // 参数:
        //   enumeration:
        public static string GetDescription(this Enum enumeration)
        {
            Type type = enumeration.GetType();
            MemberInfo[] member = type.GetMember(enumeration.ToString());
            if (member != null && member.Length != 0)
            {
                object[] customAttributes = member[0].GetCustomAttributes(typeof(DescriptionAttribute), inherit: false);
                if (customAttributes != null && customAttributes.Length != 0)
                {
                    return ((DescriptionAttribute)customAttributes[0]).Description;
                }
            }

            return enumeration.ToString();
        }

        //
        // 摘要:
        //     深拷贝
        //
        // 参数:
        //   obj:
        //
        // 类型参数:
        //   T:
        public static T DeepCopy<T>(this T obj)
        {
            if (obj == null)
            {
                return default(T);
            }

            JsonSerializerOptions options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            };
            string json = System.Text.Json.JsonSerializer.Serialize(obj, options);
            return System.Text.Json.JsonSerializer.Deserialize<T>(json, options);
        }

        //
        // 摘要:
        //     Json转字典
        //
        // 参数:
        //   jObject:
        //
        //   error:
        public static Dictionary<string, object> TryToDictionary(this JObject jObject, out Exception error)
        {
            try
            {
                error = null;
                return ToDictionaryInternal(jObject);
            }
            catch (Exception ex)
            {
                error = ex;
                return null;
            }
        }

        private static Dictionary<string, object> ToDictionaryInternal(JObject jObject)
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            foreach (JProperty item in jObject.Properties())
            {
                string name = item.Name;
                JToken value = item.Value;
                if (value is JObject jObject2)
                {
                    dictionary[name] = ToDictionaryInternal(jObject2);
                }
                else if (value is JArray jArray)
                {
                    dictionary[name] = jArray.ToObject<List<object>>();
                }
                else
                {
                    dictionary[name] = ((JValue)value).Value;
                }
            }

            return dictionary;
        }
    }
}
